`include "defines.v"

// tinyriscv处理器核顶层模块
module tinyriscv(
   
    input wire clko,
    input wire rst,
    input wire int_flag_i,//中断信号

    output wire rf_1_o,
    output wire rf_2_o,
    output wire rf_3_o,
    output wire rf_4_o
);
/*
    reg  clk;
    reg rst;
    reg int_flag_i;//中断信号

    wire rf_1_o;
    wire rf_2_o;
    wire rf_3_o;
    wire rf_4_o;

    initial
    begin
    clk = 0;
    rst = 1;
    int_flag_i=0;
    #50 rst = 0;
    #100 rst =1;
    end
    
  
 
    always #100 clk = ~clk;     // 50MHz*/
    
    reg[31:0] count;
    reg clk;
    always @(posedge clko) begin
        if  ( (rst == 0) ||  (count   ==  10000000 )) begin
            count<=0; 
            clk <= 1;
        end
        else begin
            clk <= 0;
            count <= count + 1;
        end
    end

    //rom输出信号
    wire[`MemBus] pc_data_o;    


    // pc_reg模块输出信号
	wire[`InstAddrBus] pc_pc_o;

    // if_id模块输出信号
	wire[`InstBus] if_inst_o;
    wire[`InstAddrBus] if_inst_addr_o;
    wire if_int_flag_o;

    // id模块输出信号
    wire[`RegAddrBus] id_reg1_raddr_o;
    wire[`RegAddrBus] id_reg2_raddr_o;
    wire[`InstBus] id_inst_o;
    wire[`InstAddrBus] id_inst_addr_o;
    wire[`RegBus] id_reg1_rdata_o;
    wire[`RegBus] id_reg2_rdata_o;
    wire id_reg_we_o;
    wire[`RegAddrBus] id_reg_waddr_o;
    wire[`MemAddrBus] id_csr_raddr_o;
    wire id_csr_we_o;
    wire[`RegBus] id_csr_rdata_o;
    wire[`MemAddrBus] id_csr_waddr_o;

    // id_ex模块输出信号
    wire[`InstBus] ie_inst_o;
    wire[`InstAddrBus] ie_inst_addr_o;
    wire ie_reg_we_o;
    wire[`RegAddrBus] ie_reg_waddr_o;
    wire[`RegBus] ie_reg1_rdata_o;
    wire[`RegBus] ie_reg2_rdata_o;
    wire ie_csr_we_o;
    wire[`MemAddrBus] ie_csr_waddr_o;
    wire[`RegBus] ie_csr_rdata_o;

    // ex模块输出信号
    wire[`MemBus] ex_mem_wdata_o;
    wire[`MemAddrBus] ex_mem_raddr_o;
    wire[`MemAddrBus] ex_mem_waddr_o;
    wire ex_mem_we_o;
    wire ex_mem_req_o;
    wire[`RegBus] ex_reg_wdata_o;
    wire ex_reg_we_o;
    wire[`RegAddrBus] ex_reg_waddr_o;
    wire ex_hold_flag_o;
    wire ex_jump_flag_o;
    wire[`InstAddrBus] ex_jump_addr_o;

    wire[`RegBus] ex_csr_wdata_o;
    wire ex_csr_we_o;
    wire[`MemAddrBus] ex_csr_waddr_o;

    // regs模块输出信号
    wire[`RegBus] regs_rdata1_o;
    wire[`RegBus] regs_rdata2_o;

    // ctrl模块输出信号
    wire[`Hold_Flag_Bus] ctrl_hold_flag_o;
    wire ctrl_jump_flag_o;
    wire[`InstAddrBus] ctrl_jump_addr_o;
    //ram模块输出信号
    wire[`MemBus] mem_data_o;

    // csr_reg模块输出信号
    wire[`RegBus] csr_data_o;
    wire csr_global_int_en_o;
    wire[`RegBus] csr_clint_csr_mtvec;
    wire[`RegBus] csr_clint_csr_mepc;
    wire[`RegBus] csr_clint_csr_mstatus;
    //clint 模块输出信号
    wire clint_we_o;
    wire[`MemAddrBus] clint_waddr_o;
    wire[`RegBus] clint_data_o;
    wire[`InstAddrBus] clint_int_addr_o;
    wire clint_int_assert_o;
    wire clint_hold_flag_o;

    // pc_reg模块例化
    pc_reg u_pc_reg(
        .clk(clk),
        .rst(rst),
        .pc_o(pc_pc_o),
        .hold_flag_i(ctrl_hold_flag_o),
        .jump_flag_i(ctrl_jump_flag_o),
        .jump_addr_i(ctrl_jump_addr_o)
    );

    // ctrl模块例化
    ctrl u_ctrl(
        .rst(rst),
        .jump_flag_i(ex_jump_flag_o),
        .jump_addr_i(ex_jump_addr_o),
        .hold_flag_ex_i(ex_hold_flag_o),
        .hold_flag_o(ctrl_hold_flag_o),
        .jump_flag_o(ctrl_jump_flag_o),
        .jump_addr_o(ctrl_jump_addr_o),
        .hold_flag_clint_i(clint_hold_flag_o)
    );

    // regs模块例化
    regs u_regs(
        .clk(clk),
        .rst(rst),
        .we_i(ex_reg_we_o),
        .waddr_i(ex_reg_waddr_o),
        .wdata_i(ex_reg_wdata_o),
        .raddr1_i(id_reg1_raddr_o),
        .rf_1(rf_1_o),
        .rf_2(rf_2_o),
        .rf_3(rf_3_o),
        .rf_4(rf_4_o),
        .rdata1_o(regs_rdata1_o),
        .raddr2_i(id_reg2_raddr_o),
        .rdata2_o(regs_rdata2_o)
    );

    // if_id模块例化
    if_id u_if_id(
        .clk(clk),
        .rst(rst),
        .int_flag_i(int_flag_i),
        .inst_i(pc_data_o),
        .inst_addr_i(pc_pc_o),
        .hold_flag_i(ctrl_hold_flag_o),
        .int_flag_o(if_int_flag_o),
        .inst_o(if_inst_o),
        .inst_addr_o(if_inst_addr_o)
    );

    // id模块例化
    id u_id(
        .rst(rst),
        .inst_i(if_inst_o),
        .inst_addr_i(if_inst_addr_o),

        .reg1_rdata_i(regs_rdata1_o),
        .reg2_rdata_i(regs_rdata2_o),

        .ex_jump_flag_i(ex_jump_flag_o),

        .reg1_raddr_o(id_reg1_raddr_o),
        .reg2_raddr_o(id_reg2_raddr_o),
        .csr_we_o(id_csr_we_o),
        .csr_rdata_o(id_csr_rdata_o),
        .csr_rdata_i(csr_data_o),
        .csr_waddr_o(id_csr_waddr_o),
        .csr_raddr_o(id_csr_raddr_o),
        .inst_o(id_inst_o),
        .inst_addr_o(id_inst_addr_o),
        .reg1_rdata_o(id_reg1_rdata_o),
        .reg2_rdata_o(id_reg2_rdata_o),
        .reg_we_o(id_reg_we_o),
        .reg_waddr_o(id_reg_waddr_o)
    );

    // id_ex模块例化
    id_ex u_id_ex(
        .clk(clk),
        .rst(rst),

        .inst_i(id_inst_o),
        .inst_addr_i(id_inst_addr_o),

        .csr_we_i(id_csr_we_o),
        .csr_waddr_i(id_csr_waddr_o),
        .csr_rdata_i(id_csr_rdata_o),

        .reg_we_i(id_reg_we_o),
        .reg_waddr_i(id_reg_waddr_o),

        .reg1_rdata_i(id_reg1_rdata_o),
        .reg2_rdata_i(id_reg2_rdata_o),

        .hold_flag_i(ctrl_hold_flag_o),

        .inst_o(ie_inst_o),
        .inst_addr_o(ie_inst_addr_o),
        .reg_we_o(ie_reg_we_o),
        .reg_waddr_o(ie_reg_waddr_o),
        .reg1_rdata_o(ie_reg1_rdata_o),
        .reg2_rdata_o(ie_reg2_rdata_o),

        .csr_we_o(ie_csr_we_o),
        .csr_waddr_o(ie_csr_waddr_o),
        .csr_rdata_o(ie_csr_rdata_o)
    );

    // ex模块例化
    ex u_ex(
        .rst(rst),

        .inst_i(ie_inst_o),
        .inst_addr_i(ie_inst_addr_o),
        .reg_we_i(ie_reg_we_o),
        .reg_waddr_i(ie_reg_waddr_o),
        .reg1_rdata_i(ie_reg1_rdata_o),
        .reg2_rdata_i(ie_reg2_rdata_o),

        .mem_rdata_i(mem_data_o),
        
        .csr_we_i(ie_csr_we_o),
        .csr_waddr_i(ie_csr_waddr_o),
        .csr_rdata_i(ie_csr_rdata_o),
        //to clint
        .jump_addr_o(ex_jump_addr_o),

        //from clint
        .int_assert_i(clint_int_assert_o),
        .int_addr_i(clint_int_addr_o),

        //to csr reg
        .csr_wdata_o(ex_csr_wdata_o),
        .csr_we_o(ex_csr_we_o),
        .csr_waddr_o(ex_csr_waddr_o),

        //to regs
        .reg_wdata_o(ex_reg_wdata_o),
        .reg_we_o(ex_reg_we_o),
        .reg_waddr_o(ex_reg_waddr_o),

        //to ctrl
        .hold_flag_o(ex_hold_flag_o),
        .jump_flag_o(ex_jump_flag_o),

        //to ram
        .mem_wdata_o(ex_mem_wdata_o),
        .mem_raddr_o(ex_mem_raddr_o),
        .mem_waddr_o(ex_mem_waddr_o),
        .mem_we_o(ex_mem_we_o),
        .mem_req_o(ex_mem_req_o)
    );
// rom模块例化
    rom u_rom(
    .clk(clk),
    .rst(rst),
    .addr_i(pc_pc_o),    // addr
    .data_o(pc_data_o)      // read data
    );

// ram模块例化
    ram u_ram(
    .clk(clk),
    .rst(rst),

    .raddr_i(ex_mem_raddr_o),   
    .waddr_i(ex_mem_waddr_o),
    .req_i(ex_mem_req_o),
    .we_i(ex_mem_we_o),
    .data_i(ex_mem_wdata_o),
    
    .data_o(mem_data_o)  
    );
//clint模块例化
    clint u_clint(
         .clk(clk),
        .rst(rst),
        //from if id
        .int_flag_i(if_int_flag_o),
        //from id
        .inst_i(id_inst_o),
        .inst_addr_i(id_inst_addr_o),
        //from ctrl
        .hold_flag_i(ctrl_hold_flag_o),
        //from ex
        .jump_flag_i(ex_jump_flag_o),
        .jump_addr_i(ex_jump_addr_o),
        //from csr reg
        .csr_mtvec(csr_clint_csr_mtvec),
        .csr_mepc(csr_clint_csr_mepc),
        .csr_mstatus(csr_clint_csr_mstatus),
        .global_int_en_i(csr_global_int_en_o),
        //to csr reg
        .we_o(clint_we_o),
        .waddr_o(clint_waddr_o),
        .data_o(clint_data_o),
        //to ex
        .int_assert_o(clint_int_assert_o),
        .int_addr_o(clint_int_addr_o),
        //to ctrl
        .hold_flag_o(clint_hold_flag_o)
    );
// csr_reg模块例化
    csr_reg u_csr_reg(
        .clk(clk),
        .rst(rst),
        //from id
        .raddr_i(id_csr_raddr_o),
        //from ex
        .we_i(ex_csr_we_o),
        .waddr_i(ex_csr_waddr_o),
        .data_i(ex_csr_wdata_o),
        //from clint 
        .clint_we_i(clint_we_o),
        .clint_waddr_i(clint_waddr_o),
        .clint_data_i(clint_data_o),
        //to clint
        .global_int_en_o(csr_global_int_en_o),
        .clint_csr_mepc(csr_clint_csr_mepc),
        .clint_csr_mstatus(csr_clint_csr_mstatus),
        .clint_csr_mtvec(csr_clint_csr_mtvec),
        //to id
        .data_o(csr_data_o)
    );

endmodule